﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Text;
using System.Globalization;
using System.Data;
using System.Configuration;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.Http.Filters;
using log4net;
using log4net.Config;
using System.Web.Routing;
using System.Diagnostics;


namespace MvcFilters.Filters
{

        [AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
        sealed class  TraceFilterAttribute : System.Web.Mvc.ActionFilterAttribute
        {

            private ILog logger;

            [NonSerialized]
            Stopwatch _StopWatch;

            public TraceFilterAttribute()
            {
                XmlConfigurator.Configure();
                this.logger = LogManager.GetLogger(typeof(TraceFilterAttribute));
            }
    
            //se llama antes de la ejecucion del metodo.
            public override void OnActionExecuting(ActionExecutingContext filterContext)
            {
                this._StopWatch = Stopwatch.StartNew();

                ReflectedActionDescriptor rad = (ReflectedActionDescriptor)filterContext.ActionDescriptor;
                String nombreAccion = rad.ActionName;

                String nombreControlador = filterContext.Controller.GetType().FullName;

                StringBuilder builder = new StringBuilder();
                filterContext.ActionParameters.ToList().ForEach(a => builder.AppendFormat("{0}:{1}; ", a.Key, a.Value ?? "{empty}"));
                var parameters = builder.ToString();

                String mensaje = "ENTRANDO en [" + nombreAccion + "] del controlador [" + nombreControlador + "] con los parametros =>" + (string.IsNullOrEmpty(parameters) ? "(sin parámetros)" : parameters);

                this.logger.Debug(mensaje);
            }

            //se llama despues de la ejecucion del metodo.
            public override void OnActionExecuted(ActionExecutedContext filterContext)
            {
                long milisegundos = _StopWatch.ElapsedMilliseconds;

                ReflectedActionDescriptor rad = (ReflectedActionDescriptor)filterContext.ActionDescriptor;
                String nombreAccion = rad.ActionName;

                String nombreControlador = filterContext.Controller.GetType().FullName;

                String mensaje = "SALIENDO de [" + nombreAccion + "] del controlador [" + nombreControlador + "]. La operación tardó " + milisegundos.ToString() + "ms.";
                this.logger.Debug(mensaje);
            }

            
        }

}